﻿using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework.Graphics;
using tutFuelCellGame.Sprites;
using ZoomEngine.Animation;

namespace tutFuelCellGame
{

    public class BarrierAnimationData
    {
        public float barrierAlpha;
    }

    /// <summary>
    /// Manages the animations within the game
    /// </summary>
    public class AnimationManager
    {
        ClockManager clockManager;

        private Clock currentBarrierClock;
        private FloatFromToAnimation riseUp;
        private FloatFromToAnimation flyOff;
        private FloatFromToAnimation turnAway;

        public AnimationManager(ClockManager clockManager)
        {
            this.clockManager = clockManager;
        }

        public void StartBarrierAnimation(BarrierAnimationData data)
        {
            const float deceleration = .7f;
            const float transitionTime = 0.5f;
            const float holdingTime = 0.8f;

            var animBarrierAlpha = new FloatFromToAnimation(clockManager)
            {
                From = data.barrierAlpha,
                To = GameConstants.BarrierAlphaGameLost,
                RepeatCount = 0,
                AutoReverse = false,
                Duration = transitionTime,
                ProgressTransform = ProgressTransforms.Decelerate(deceleration),
                Apply = (v) => { data.barrierAlpha = v; }
            };
            animBarrierAlpha.Complete += (e, s) =>
            {
                //barrierAlpha = GameConstants.BarrierAlphaGameLost;
                var holder = new Timer(clockManager) { Duration = holdingTime, RepeatCount = 3};
                StartBarrierClock(holder);
                holder.Complete += (ex, sx) =>
                {
                    var animBarrierAlpha2 = new FloatFromToAnimation(clockManager)
                    {
                        From = data.barrierAlpha,
                        To = GameConstants.BarrierAlphaNormal,
                        RepeatCount = 0,
                        AutoReverse = false,
                        Duration = transitionTime,
                        ProgressTransform = ProgressTransforms.Decelerate(deceleration),
                        Apply = (v) => { data.barrierAlpha = v; }
                    };
                    StartBarrierClock(animBarrierAlpha2);
                    animBarrierAlpha2.Complete += (et, st) =>
                    {
                        //      barrierAlpha = GameConstants.BarrierAlphaNormal;
                        var holder2 = new Timer(clockManager) { Duration = holdingTime };
                        StartBarrierClock(holder2);
                        holder2.Complete += (e3, s3) =>
                            StartBarrierAnimation(data);
                    };
                };
            };
            StartBarrierClock(animBarrierAlpha);
        }

        private void StartBarrierClock(Clock clock)
        {
            currentBarrierClock = clock;
            clock.Start();
        }



        internal void StopAllAnimations()
        {
            if (currentBarrierClock != null) currentBarrierClock.Stop();
            if (riseUp != null) riseUp.Stop();
            if (flyOff != null) flyOff.Stop();
            if (turnAway != null) turnAway.Stop();
        }

        internal void PlayGameWonAnimation(FuelCarrier fuelCarrier)
        {
            riseUp = new FloatFromToAnimation(clockManager)
                         {
                             From = fuelCarrier.Height,
                             To = fuelCarrier.Height*10f,
                             ProgressTransform = ProgressTransforms.Decelerate(1.3f),
                             Duration = 2.5f,
                             BeginOffset = 1.2f,
                             Apply = (v) => { fuelCarrier.Height = v; }
                         };
            flyOff = new FloatFromToAnimation(clockManager)
                         {
                             From = GameConstants.MaxVelocity - 0.001f,
                             To = GameConstants.MaxVelocity,
                             ProgressTransform = ProgressTransforms.Accelerate(3f),
                             Duration = 10.5f,
                             BeginOffset = 4f,
                             Apply = (v) => { fuelCarrier.Thrust = v; }
                         };
            turnAway = new FloatFromToAnimation(clockManager)
                           {
                               From = fuelCarrier.TurnImpulse,
                               To = 1f,
                               ProgressTransform = ProgressTransforms.Accelerate(3f),
                               Duration = 1f,
                               BeginOffset = 5.5f,
                               Apply = (v) => { fuelCarrier.TurnImpulse = v; }
                           };
            riseUp.Start();
            flyOff.Start();
            turnAway.Start();
        }

        public LevelCountDown StartCountDown(int level, SpriteFont font)
        {
            var countDown = new LevelCountDown(font);
            var sizeAnimation = new FloatFromToAnimation(clockManager)
                                {
                                    From = 0.1f,
                                    To = 1f,
                                    Duration = 1f,
                                    RepeatCount = 4,
                                    ProgressTransform = ProgressTransforms.EaseOutBack(),
                                    Apply = v => countDown.Scale = v,
                                };
            var opacityAnimation = new FloatFromToAnimation(clockManager)
            {
                From = 1f,
                To = 0.1f,
                Duration = 1f,
                RepeatCount = 4,
                Apply = v => countDown.Opacity = v,
            };
            opacityAnimation.Start();
            sizeAnimation.Start();
            sizeAnimation.Complete += CountDownComplete;
            return countDown;
        }

        public event EventHandler CountDownComplete;

        public void StartHUDFuelCellAnimation(Sprite sprite)
        {
            var sizeAnimation = new FloatFromToAnimation(clockManager)
            {
                From = sprite.Scale,
                To = sprite.Scale * 1.5f,
                Duration = .3f,
                AutoReverse = true,
                Apply = v => sprite.Scale = v,
            };
            var opacityAnimation = new FloatFromToAnimation(clockManager)
            {
                From = sprite.Opacity,
                To = 1f,
                Duration = .3f,
                Apply = v => sprite.Opacity = v,
            };
            opacityAnimation.Start();
            sizeAnimation.Start();
        }
    }
}
